"""
合规性专家代理 - 负责检查内容是否符合规则规范法律要求
"""

from typing import Dict, List, Any, Optional
import time
from loguru import logger

from .base_agent import BaseAgent, AgentResult, ReviewItem
from ..utils.data_loader import ProcessingElement


class ComplianceAgent(BaseAgent):
    """合规性专家代理"""
    
    def __init__(self, api_client, config: Dict[str, Any], rules_content: str = ""):
        super().__init__(
            name="合规性专家",
            agent_type="compliance",
            api_client=api_client,
            config=config
        )
        self.rules_content = rules_content
    
    def get_system_prompt(self) -> str:
        """获取系统提示词"""
        return f"""你是城市更新规划合规性审查专家。直接审查规划方案的法律法规符合性，识别合规风险并给出具体建议。

审查重点：
1. 规划合规性 - 城市总体规划、控制性详细规划符合性
2. 建设标准 - 容积率、建筑密度、绿地率等技术指标
3. 环保合规 - 环境影响评估、污染防治措施完备性
4. 安全合规 - 消防、结构、施工安全标准符合性
5. 程序合规 - 审批、公示、征收程序完整性
6. 公共利益 - 公共设施、公共空间保障情况
7. 历史保护 - 文物、历史建筑保护措施

审查依据：
{self.rules_content[:2000] if self.rules_content else "相关城市更新法规和技术规范"}

评分标准（总分100分）：
1. 法规符合性（30分）：城市规划法规、建设法规符合性
2. 标准符合性（25分）：技术标准、行业规范符合性
3. 政策符合性（25分）：政府政策、规划要求符合性
4. 程序合规性（20分）：审批程序、公众参与程序完整性

扣分规则：
- critical问题：每项扣5分
- major问题：每项扣3分
- minor问题：每项扣1分

置信度计算：基于法规掌握程度、问题识别准确性、合规检查覆盖度

输出JSON格式：
{{
  "findings": [
    {{
      "item_id": "compliance_001",
      "severity": "critical/major/minor/info",
      "category": "规划合规性/建设标准/环保合规/安全合规/程序合规/公共利益/历史保护",
      "description": "具体问题描述",
      "suggestion": "改进建议",
      "regulation": "相关法规条款",
      "location": "问题位置",
      "confidence": 0.9,
      "score_impact": -3,
      "check_item": "法规符合性"
    }}
  ],
  "summary": "总体合规性评估",
  "scoring_details": {{
    "regulation_compliance_score": 25,
    "standard_compliance_score": 22,
    "policy_compliance_score": 23,
    "procedure_compliance_score": 18,
    "total_score": 88,
    "deduction_details": "扣分详情说明"
  }}
}}

严重性等级：critical(严重违规)、major(重要问题)、minor(轻微瑕疵)、info(优化建议)

直接输出审查结果，无需询问或说明。"""
    
    def process(self, data: Any, context: Dict[str, Any] = None) -> AgentResult:
        """处理数据并返回合规性审查结果"""
        start_time = time.time()
        
        if not self.validate_input(data):
            return self.handle_api_error(
                Exception("输入数据无效"), 
                "合规性检查"
            )
        
        try:
            # 提取需要合规检查的内容
            content_to_check = self._extract_compliance_content(data)
            
            if not content_to_check:
                return self.create_result(
                    success=True,
                    findings=[],
                    summary="无内容需要进行合规性检查",
                    confidence=1.0,
                    processing_time=time.time() - start_time
                )
            
            self.log_processing_start(f"合规性检查，内容长度: {len(content_to_check)}")
            
            # 构建合规检查提示
            prompt = self._build_compliance_check_prompt(content_to_check, context)
            
            # 调用API进行合规分析
            response = self.api_client.chat_completion(
                messages=[
                    {"role": "system", "content": self.get_system_prompt()},
                    {"role": "user", "content": prompt}
                ],
                model=self.config.get('text_model', 'Qwen/Qwen2.5-7B-Instruct')
            )
            
            # 解析响应
            review_items = self.parse_llm_response(response)
            
            # 添加基于规则的检查
            rule_based_items = self._perform_rule_based_check(content_to_check)
            review_items.extend(rule_based_items)
            
            # 获取location信息
            locations = context.get('locations', '未知位置') if context else '未知位置'
            
            # 生成结果
            processing_time = time.time() - start_time
            findings = self.format_findings(review_items, default_location=locations)
            summary = self.generate_summary(review_items)
            confidence = self.calculate_confidence(review_items)
            
            self.log_processing_end(True, processing_time, len(findings))
            
            return self.create_result(
                success=True,
                findings=findings,
                summary=summary,
                confidence=confidence,
                processing_time=processing_time,
                metadata={
                    "content_length": len(content_to_check),
                    "compliance_checks_performed": len(review_items),
                    "rules_applied": bool(self.rules_content),
                    "agent_type": self.agent_type
                },
                locations=locations
            )
            
        except Exception as e:
            return self.handle_api_error(e, "合规性检查")
    
    def _extract_compliance_content(self, data: Any) -> str:
        """提取需要合规检查的内容"""
        content_parts = []
        
        if isinstance(data, list):
            for item in data:
                if isinstance(item, ProcessingElement):
                    if item.source_type in ['text', 'table'] and item.content:
                        # 重点关注规划、建设、环保等相关内容
                        if self._is_compliance_relevant(item.category, item.subcategory, item.content):
                            content_parts.append(f"[{item.category}-{item.subcategory}] {item.content}")
                elif isinstance(item, dict):
                    # 处理分组数据
                    if 'elements' in item:
                        # 这是一个分组，处理其中的元素
                        for element in item['elements']:
                            content = element.get('content', '')
                            category = element.get('category', '')
                            subcategory = element.get('subcategory', '')
                            if content and self._is_compliance_relevant(category, subcategory, content):
                                content_parts.append(f"[{category}-{subcategory}] {content}")
                    else:
                        # 单个元素
                        content = item.get('content', '')
                        category = item.get('category', '')
                        if content and self._is_compliance_relevant(category, '', content):
                            content_parts.append(f"[{category}] {content}")
        elif isinstance(data, ProcessingElement):
            if data.source_type in ['text', 'table'] and data.content:
                content_parts.append(data.content)
        elif isinstance(data, dict):
            # 处理分组数据
            if 'elements' in data:
                # 这是一个分组，处理其中的元素
                for element in data['elements']:
                    content = element.get('content', '')
                    category = element.get('category', '')
                    subcategory = element.get('subcategory', '')
                    if content and self._is_compliance_relevant(category, subcategory, content):
                        content_parts.append(f"[{category}-{subcategory}] {content}")
            else:
                # 单个元素
                content = data.get('content', '')
                if content:
                    content_parts.append(content)
        elif isinstance(data, str):
            content_parts.append(data)
        
        return "\n\n".join(content_parts)
    
    def _is_compliance_relevant(self, category: str, subcategory: str, content: str) -> bool:
        """判断内容是否与合规性相关"""
        compliance_keywords = [
            '规划', '建设', '环保', '安全', '消防', '绿地', '容积率', '建筑密度',
            '公共设施', '交通', '基础设施', '环境影响', '文物保护', '历史建筑',
            '审批', '许可', '标准', '规范', '法规', '条例', '要求', '指标'
        ]
        
        text_to_check = f"{category} {subcategory} {content}".lower()
        
        return any(keyword in text_to_check for keyword in compliance_keywords)
    
    def _build_compliance_check_prompt(self, content: str, context: Dict[str, Any] = None) -> str:
        """构建合规检查提示"""
        prompt_parts = [
            "对以下城市更新方案册内容进行合规性审查：",
            "",
            "=== 待审查内容 ===",
            content[:4000],  # 限制长度
        ]
        
        if len(content) > 4000:
            prompt_parts.append("\n[注：内容已截断，仅显示前4000字符]")
        
        prompt_parts.extend([
            "",
            "=== 合规审查要求 ===",
            "重点检查以下合规性问题：",
            "1. 规划合规性：是否符合城市规划要求",
            "2. 建设标准：各项技术指标是否达标",
            "3. 环保要求：环境保护措施是否到位",
            "4. 安全标准：消防、结构等安全要求",
            "5. 公共利益：公共设施和空间保障",
            "6. 程序合规：审批流程和公众参与",
            "7. 文化保护：历史文化保护措施",
            "",
            "按照系统提示中的JSON格式输出审查结果，并在每个问题中标注相关的法规条款。"
        ])
        
        if context:
            prompt_parts.extend([
                "",
                "=== 项目背景 ===",
                f"项目类型: {context.get('project_type', '城市更新')}",
                f"项目规模: {context.get('project_scale', '未知')}",
                f"所在区域: {context.get('location', '未知')}",
            ])
        
        return "\n".join(prompt_parts)
    
    def _perform_rule_based_check(self, content: str) -> List[ReviewItem]:
        """执行基于规则的检查"""
        review_items = []
        
        if not self.rules_content:
            return review_items
        
        # 检查关键指标
        indicators_to_check = {
            '容积率': r'容积率.*?(\d+\.?\d*)',
            '建筑密度': r'建筑密度.*?(\d+\.?\d*)%?',
            '绿地率': r'绿地率.*?(\d+\.?\d*)%?',
            '建筑高度': r'建筑高度.*?(\d+\.?\d*)米?'
        }
        
        import re
        
        for indicator, pattern in indicators_to_check.items():
            matches = re.findall(pattern, content, re.IGNORECASE)
            if matches:
                # 这里可以添加具体的指标检查逻辑
                # 例如检查容积率是否超标等
                for match in matches:
                    try:
                        value = float(match)
                        check_result = self._check_indicator_compliance(indicator, value)
                        if check_result:
                            review_items.append(check_result)
                    except ValueError:
                        continue
        
        # 检查必需的审批程序
        required_procedures = ['环评', '规划许可', '建设许可', '消防审查']
        for procedure in required_procedures:
            if procedure not in content:
                review_items.append(self.create_review_item(
                    item_id=f"compliance_procedure_{procedure}",
                    category="程序合规",
                    severity="major",
                    description=f"未发现{procedure}相关内容",
                    suggestion=f"请补充{procedure}的相关说明和文件"
                ))
        
        return review_items
    
    def _check_indicator_compliance(self, indicator: str, value: float) -> Optional[ReviewItem]:
        """检查具体指标的合规性"""
        # 这里可以根据实际的规范标准进行检查
        # 以下是示例逻辑
        
        if indicator == '容积率':
            if value > 5.0:  # 假设的上限
                return self.create_review_item(
                    item_id=f"compliance_far_{value}",
                    category="建设标准",
                    severity="critical",
                    description=f"容积率{value}可能超出规范要求",
                    suggestion="请核实容积率是否符合控制性详细规划要求"
                )
        elif indicator == '建筑密度':
            if value > 60:  # 假设的上限
                return self.create_review_item(
                    item_id=f"compliance_density_{value}",
                    category="建设标准",
                    severity="major",
                    description=f"建筑密度{value}%可能过高",
                    suggestion="请检查建筑密度是否符合规划要求"
                )
        elif indicator == '绿地率':
            if value < 30:  # 假设的下限
                return self.create_review_item(
                    item_id=f"compliance_green_{value}",
                    category="环境保护",
                    severity="major",
                    description=f"绿地率{value}%可能不足",
                    suggestion="请确保绿地率满足规范要求"
                )
        
        return None
    
    def set_rules_content(self, rules_content: str):
        """设置规则内容"""
        self.rules_content = rules_content
        logger.info(f"合规性专家已更新规则内容，长度: {len(rules_content)}")
    
    def get_compliance_categories(self) -> List[str]:
        """获取合规性检查类别"""
        return [
            "规划合规性",
            "建设标准",
            "环境保护",
            "安全要求",
            "公共利益",
            "程序合规",
            "文化保护"
        ]
    
    def calculate_detailed_score(self, review_items: List[ReviewItem]) -> Dict[str, Any]:
        """计算详细评分"""
        # 初始分数
        scores = {
            "regulation_compliance_score": 30,  # 法规符合性
            "standard_compliance_score": 25,    # 标准符合性
            "policy_compliance_score": 25,      # 政策符合性
            "procedure_compliance_score": 20    # 程序合规性
        }
        
        deductions = {
            "regulation_compliance_score": 0,
            "standard_compliance_score": 0,
            "policy_compliance_score": 0,
            "procedure_compliance_score": 0
        }
        
        deduction_details = []
        
        # 根据问题类型和严重性扣分
        for item in review_items:
            severity_deduction = {"critical": 5, "major": 3, "minor": 1}.get(item.severity, 0)
            
            # 根据问题类别分配扣分
            if "规划" in item.category or "法规" in item.category:
                deductions["regulation_compliance_score"] += severity_deduction
                deduction_details.append(f"法规符合性扣{severity_deduction}分: {item.description[:30]}...")
            elif "标准" in item.category or "技术" in item.category or "建设" in item.category:
                deductions["standard_compliance_score"] += severity_deduction
                deduction_details.append(f"标准符合性扣{severity_deduction}分: {item.description[:30]}...")
            elif "政策" in item.category or "要求" in item.category:
                deductions["policy_compliance_score"] += severity_deduction
                deduction_details.append(f"政策符合性扣{severity_deduction}分: {item.description[:30]}...")
            elif "程序" in item.category or "审批" in item.category or "许可" in item.category:
                deductions["procedure_compliance_score"] += severity_deduction
                deduction_details.append(f"程序合规性扣{severity_deduction}分: {item.description[:30]}...")
            else:
                # 默认扣法规符合性分
                deductions["regulation_compliance_score"] += severity_deduction
                deduction_details.append(f"合规问题扣{severity_deduction}分: {item.description[:30]}...")
        
        # 计算最终分数
        final_scores = {}
        for key, base_score in scores.items():
            final_scores[key] = max(0, base_score - deductions[key])
        
        total_score = sum(final_scores.values())
        
        return {
            **final_scores,
            "total_score": total_score,
            "deduction_details": "; ".join(deduction_details) if deduction_details else "无扣分项"
        }